home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir36
/
ask_dos.zip
/
ASK.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-03-05
|
10KB
|
321 lines
TITLE Program ASK.ASM - GROUP directive used in construct for .COM file.
; *************************************************************************
; * Date: March 31, 1992 Use: Interactive Batch Processing. *
; * *
; * Written by: Patrick Whittle (519) 945-7596 *
; * Revised to .COM format March 5, 1994 *
; *************************************************************************
CR EQU 0Dh
LF EQU 0Ah
SPACE EQU 20h
comGrp GROUP dSeg1, dSeg2, cSeg
cSeg SEGMENT WORD 'CODE' ; Give names to our segments.
cSeg ENDS
dSeg1 SEGMENT WORD PUBLIC 'DATA'
dSeg1 ENDS
dSeg2 SEGMENT WORD PUBLIC 'DATA'
dSeg2 ENDS
dSeg1 SEGMENT ; Data segment 1 for initialized data.
;
MESSAGE DB 'Batch Enhancer, written by Patrick Whittle, (519) 945-7596.', CR, LF, CR, LF
DB 'USAGE:', CR, LF
DB 09h, 'ASK [Prompt to display]', CR, LF
DB 09h, 'ASK [/?]', CR, LF, CR, LF
DB 'Returns DOS errorlevel.', CR, LF, 00h
;
PROMPT DB '(Y or N)? ', 00h
YES DB 'YES', 00h
NO DB 'NO', 00h
;
ctrlText DB CR, LF, '<Break>', CR, LF, 00h
dSeg1 ENDS
dSeg2 SEGMENT ; Data segment 2 for un-initialized data.
;
errorlevel DB ?
origSegment DW ?
origOffset DW ?
;
dSeg2 ENDS
cSeg SEGMENT
ASSUME cs:comGrp, ds:comGrp, es:comGrp, ss:comGrp
ORG 100h ; Start of CS and DS
Main:
call grabCommandline ; Command-line tail given?
jcxz sendInstruction ; If not, send out prompt.
cmp WORD PTR [si], '?/'
je sendHelp
mov bx, si ; SI contains pointer to cmd-line argument.
call dispString ; Display user supplied string.
ContinueMain:
call getIntVector
lea dx, ctrlBreakHandler
call setIntVector
call Validate ; Compare inputed keys with Y and N.
Stop:
push ds
mov dx, comGrp:origOffset
mov ds, comGrp:origSegment
call setIntVector
pop ds
DOSexit:
mov ah, 4Ch ; Program Terminate with errorlevel.
mov al, comGrp:errorlevel
int 21h
sendInstruction:
call OutPut
jmp ContinueMain ; Proceed and validate input.
sendHelp:
lea bx, MESSAGE
call dispString
mov comGrp:errorlevel, 00h
jmp DOSexit
;---------------------------
Validate PROC NEAR
call AcceptChar
cmp al, 'Y' ; Is this the "Y" character?
je YWasTyped
cmp al, 'N' ; Is this the "N" character?
je NWastyped
call Cr_Lf
call OutPut ; Conditions not met.
jmp Validate ; Unconditional jump.
YWasTyped:
lea bx, comGrp:YES ; Load Effective Address into BX.
call dispString
call Cr_Lf
mov comGrp:errorlevel, 00h ; Set DOS errorlevel to zero.
jmp CharactersFine
NWasTyped:
lea bx, comGrp:NO
call dispString
call Cr_Lf
mov comGrp:errorlevel, 01h ; Set DOS errorlevel to one.
CharactersFine:
ret
Validate ENDP
Output PROC NEAR
lea bx, PROMPT
call dispString
ret ; Return to calling module.
Output ENDP
dispString PROC NEAR
mov ah, 02h
sendPrompt:
cmp BYTE PTR [bx], 00h
je promptDone
mov dl, BYTE PTR [bx]
int 21h
inc bx
jmp sendPrompt
promptDone:
ret
dispString ENDP
AcceptChar PROC NEAR
mov ah, 08 ; Accept character function.
int 21h
call upCase
ret ; Return to calling module.
AcceptChar ENDP
Cr_Lf PROC NEAR
mov ah, 02h
mov dl, CR
int 21h
mov dl, LF
int 21h
ret ; Return to calling module.
Cr_Lf ENDP
grabCommandline PROC NEAR
;
; Any command-line parameters supplied by the user will be passed by DOS into
; the executing programs PSP (Program Segment Prefix) area. The default PSP
; area in a program, weather in .EXE format or .COM format, is between offset
; 0000 and 0100h of the programs data segment. Since a program in .COM format
; has its code, data, and stack stored in the same segment of memory
; (i.e. CS=DS=SS respectively) it is necessary that the code of .COM programs
; always starts at offset 0100h (see ORG directive at start of this program).
;
; This PROCedure uses SI register to access the PSP making use of a flag set
; by DOS at offset 80h. This single byte indicates weather a command-line
; argument was supplied or not. If the value at offset 80h is zero, then
; no command-line argument was supplied. If the value is non-zero, the
; contents of offset 80h will hold a byte count for the supplied argument.
;
; In this procedure, the CX register will receive a copy of the byte at
; offset 80h to be used in calculating the end address of the string. All
; preceding, and trailing spaces will be discarded.
;
; Inputs:
; None
;
; Output:
; si - Pointer to start of user supplied string.
; cx - zero if no command-line argument given.
;
; Registers modified:
; cx, si
;
xor cx, cx ; Zero out cx register.
mov si, 80h
cmp BYTE PTR [si], 00h
je grabDone ; If byte at offset 80h is 0 then there were
; no arguments.
mov cl, BYTE PTR [si] ; Move byte pointed to by SI into CL register.
findNonblank:
inc si
cmp BYTE PTR [si], SPACE
jne startFound
loop findNonblank ; Assume length of argument is one less now
; as loop decrements CX register.
startFound:
jcxz grabDone ; If CX is zero then the user has supplied
; a string of spaces and just pressed ┘
push si ; Save start of argument.
add si, cx ; To point to end.
testForTrailingBlank:
dec si
cmp BYTE PTR [si], SPACE
jne terminateArgument
loop testForTrailingBlank ; Remove unwanted spaces.
terminateArgument:
mov WORD PTR [si+1], 0020h ; Add space and ensure string is ASCIIZ.
pop si
grabDone:
ret
grabCommandline ENDP
ctrlBreakHandler PROC NEAR
;
; This PROCedure is the replacement interrupt handler for int 23h - the
; Ctrl-Break interrupt. Regardless where the machine is currently executing
; in memory, the Ctrl-C interrupt will instantly force execution to branch
; to this area. The int 23h handler will be restored when ASK.COM terminates.
;
; The value of all segment registers will be unchanged when an interrupt is
; encountered. Since this program is not a TSR (Terminate and Stay Resident)
; we don't need to worry about initializing DS to point to our data for
; example, or any other segment registers.
;
; If this were a TSR program or device driver on the other hand, segment
; registers would not contain values reflecting the location of code, data,
; etc., for ASK.COM, they would contain values that were part of some other
; executing program at the time of the interrupt.
;
; The way the internal interrupt vectors are designed on Intel machines is
; such that only the CS:IP registers (code segment:instruction pointer) are
; modified when a certain interrupt is encountered, and a FAR return address
; is then pushed onto the stack (segment:offset = current execution address
; of interrupted program). It is up to the "interruptor" (i.e. the device
; driver, or TSR program) to first set up segment registers to point to its
; needed data, stack etc., and when finished, restore CS:IP with an iret
; instruction once the service requested of the device driver is complete.
;
; Output:
; Program terminates with DOS errorlevel 2
;
; Registers modified:
; ax, bx, cx
;
mov ax, cs ; The next three move intstructions are
mov ds, ax ; not needed in the context of this program,
mov es, ax ; but are included for demonstration.
mov comGrp:errorlevel, 02h
lea bx, comGrp:ctrlText
call dispString
mov ax, 0C00h ; Flush keyboard buffer.
int 21h
jmp Stop
ctrlBreakHandler ENDP
upCase PROC NEAR
;
; This function returns the corresponding upper-case letter for
; the lower-case letter passed in al.
;
; Input:
; al - contains the ASCII value for a lower-case letter
; Output:
; al - contains the ASCII value for the corresponding upper-case
; letter.
;
; Registers modified:
; al
;
; Convert the letter in AL to upper-case.
;
cmp al, 'a'
jb upcas1
cmp al, 'z'
ja upcas1
sub al, 20h
upcas1:
ret
upCase ENDP
setIntVector PROC NEAR
;
; DX register must be initialized first before calling.
;
mov ax, 2523h
int 21h
ret
setIntVector ENDP
getIntVector PROC NEAR
push es
mov ax, 3523h ; 23 is ctrl-break location in interrupt
int 21h ; vector table.
mov WORD PTR comGrp:origSegment, es
mov WORD PTR comGrp:origOffset, bx
pop es
ret
getIntVector ENDP
cSeg ENDS
END Main